package com.example.sandbox.controller.channel.pay58;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.sandbox.controller.notice.PayComponent;
import com.example.sandbox.dto.AccountQueryRequest;
import com.example.sandbox.dto.Enum.Currency;
import com.example.sandbox.dto.Enum.Order58payStatus;
import com.example.sandbox.dto.Merchant58Request;
import com.example.sandbox.dto.domain.AccountBalance;
import com.example.sandbox.dto.domain.PayOrder;
import com.example.sandbox.mapper.AccountBalanceMapper;
import com.example.sandbox.mapper.PayOrderMapper;
import com.example.sandbox.util.AmountUtil;
import com.example.sandbox.util.RandomStringGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;

@Slf4j
@RestController
public class Pay58PayOrderController {

    @Autowired
    private PayOrderMapper payOrderMapper;
    @Autowired
    private AccountBalanceMapper accountBalanceMapper;
    @Autowired
    private PayComponent payComponent;
    @Autowired
    private Executor generalExecutor;
    @GetMapping("/gateway/v1/sandbox/charge/simulatePaymentS/{tradeNo}")
    public String simulatePaymentS(@PathVariable("tradeNo") String tradeNo) throws IOException {
        if (StringUtils.isEmpty(tradeNo)){
            return "Please enter the order number";
        }
        QueryWrapper<PayOrder> query = new QueryWrapper<>();
        query.eq("pay_order_id", tradeNo).eq("state", PayOrder.STATE_ING);
        PayOrder payOrder = payOrderMapper.selectOne(query);
        if (Objects.isNull(payOrder)){
            return "The order does not exist or the order status is not in the payment process";
        }
        payOrder.setState(PayOrder.STATE_SUCCESS);
        int isUpdated = payOrderMapper.update(payOrder, query);
        if (isUpdated > 0) {
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("createdAt", payOrder.getCreatedAt().getTime() ); // 订单创建时间, 13位时间戳
            dataMap.put("amount", AmountUtil.convertCent2Dollar(payOrder.getAmount(), Currency.BRL.getCurrency())); // 支付金额（3位小数）
            dataMap.put("tradeNo", payOrder.getPayOrderId()); // 系统支付订单号
            dataMap.put("clientRequestId", payOrder.getMchOrderNo()); // 商户传入的订单号
            dataMap.put("subject", payOrder.getSubject()); // 商品标题
            dataMap.put("successTime", System.currentTimeMillis() ); // 订单支付成功时间, 13位时间戳
            dataMap.put("sign", System.currentTimeMillis() ); // 订单支付成功时间, 13位时间戳
            dataMap.put("state", Order58payStatus.getValueByKey(PayOrder.STATE_SUCCESS)); // 支付订单状态
            dataMap.put("reqTime", System.currentTimeMillis()); // 支付订单状态
            dataMap.put("body", payOrder.getBody()); // 商品描述
            dataMap.put("endToEndId", "E" + RandomStringGenerator.generateRandomString()); //  E2E订单号
            dataMap.put("merchantNo", payOrder.getMchNo()); // 商户号
            dataMap.put("errCode", null);
            dataMap.put("errMsg", null);
            generalExecutor.execute(() -> {
                try {
                    payComponent.notifyPaymentPay(dataMap, payOrder.getNotifyUrl(), "application/json");
                } catch (IOException e) {
                    log.error("58 - 支付成功通知异常 url:{}", payOrder.getNotifyUrl());
                    throw new RuntimeException(e);
                }
            });
            return "SUCCESS";
        }
        return "FAIL";
    }

    @GetMapping("/gateway/v1/sandbox/charge/simulatePaymentF/{tradeNo}")
    public String simulatePaymentF(@PathVariable("tradeNo") String tradeNo) throws IOException {
        if (StringUtils.isEmpty(tradeNo)){
            return "Please enter the order number";
        }
        QueryWrapper<PayOrder> query = new QueryWrapper<>();
        query.eq("pay_order_id", tradeNo).eq("state", PayOrder.STATE_ING);
        PayOrder payOrder = payOrderMapper.selectOne(query);
        if (Objects.isNull(payOrder)){
            return "The order does not exist or the order status is not in the payment process";
        }
        payOrder.setState(PayOrder.STATE_FAIL);
        int isUpdated = payOrderMapper.update(payOrder, query);
        if (isUpdated > 0) {
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("createdAt", payOrder.getCreatedAt().getTime() ); // 订单创建时间, 13位时间戳
            dataMap.put("amount", AmountUtil.convertCent2Dollar(payOrder.getAmount(), Currency.BRL.getCurrency())); // 支付金额（3位小数）
            dataMap.put("tradeNo", payOrder.getPayOrderId()); // 系统支付订单号
            dataMap.put("clientRequestId", payOrder.getMchOrderNo()); // 商户传入的订单号
            dataMap.put("subject", payOrder.getSubject()); // 商品标题
            dataMap.put("successTime", System.currentTimeMillis() ); // 订单支付成功时间, 13位时间戳
            dataMap.put("sign", System.currentTimeMillis() ); // 订单支付成功时间, 13位时间戳
            dataMap.put("state", Order58payStatus.getValueByKey(PayOrder.STATE_FAIL)); // 支付订单状态
            dataMap.put("reqTime", System.currentTimeMillis()); // 支付订单状态
            dataMap.put("body", payOrder.getBody()); // 商品描述
            dataMap.put("endToEndId", "E" + RandomStringGenerator.generateRandomString()); //  E2E订单号
            dataMap.put("merchantNo", payOrder.getMchNo()); // 商户号
            dataMap.put("errCode", null);
            dataMap.put("errMsg", null);
            generalExecutor.execute(() -> {
                try {
                    payComponent.notifyPaymentPay(dataMap, payOrder.getNotifyUrl(), "application/json");
                } catch (IOException e) {
                    log.error("58 - 支付失败通知异常 url:{}", payOrder.getNotifyUrl());
                    throw new RuntimeException(e);
                }
            });
            return "SUCCESS";
        }
        return "FAIL";
    }

    @PostMapping("/gateway/v1/pay/brazil/queryCharge")
    public Map queryOrder(@RequestBody Merchant58Request request) {

        if (StringUtils.isEmpty(request.getClientRequestId()) && StringUtils.isEmpty(request.getTradeNo())){
            Map map = new HashMap();
            map.put("msg", "Either tradeNo or clientRequestId must be selected");
            return map;
        }
        String payOrderId = (request.getTradeNo() != null && !request.getTradeNo().isEmpty()) ? request.getTradeNo() : "";
        String mchOrderNo = (request.getClientRequestId() != null && !request.getClientRequestId().isEmpty()) ? request.getClientRequestId() : "";
        QueryWrapper<PayOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mch_no", request.getMerchantNo());
        queryWrapper.eq(StringUtils.isNotEmpty(payOrderId),"pay_order_id", payOrderId);
        queryWrapper.eq(StringUtils.isNotEmpty(mchOrderNo),"mch_order_no", mchOrderNo);
        PayOrder payOrder = payOrderMapper.selectOne(queryWrapper);
        if (Objects.isNull(payOrder)){
            Map map = new HashMap();
            map.put("msg", "Order does not exist");
            return map;
        }
        // 创建一个 Map 用于存放响应数据
        Map<String, Object> responseMap = new HashMap<>();

        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("tradeNo", payOrder.getPayOrderId()); // 系统支付订单号
        dataMap.put("merchantNo", payOrder.getMchNo()); // 商户号
        dataMap.put("clientRequestId", payOrder.getMchOrderNo()); // 商户传入的订单号
        dataMap.put("amount", AmountUtil.convertCent2Dollar(payOrder.getAmount(), Currency.BRL.getCurrency())); // 支付金额（3位小数）
        dataMap.put("state", Order58payStatus.getValueByKey(payOrder.getState())); // 支付订单状态
        dataMap.put("subject", payOrder.getSubject()); // 商品标题
        dataMap.put("body", payOrder.getBody()); // 商品描述
        dataMap.put("endToEndId", "E" + RandomStringGenerator.generateRandomString()); //  E2E订单号
        dataMap.put("createdAt", payOrder.getCreatedAt().getTime() ); // 订单创建时间, 13位时间戳
        dataMap.put("successTime", System.currentTimeMillis() ); // 订单支付成功时间, 13位时间戳
        dataMap.put("errCode", null);
        dataMap.put("errMsg", null);

        responseMap.put("code", 0);
        responseMap.put("msg", "SUCCESS");
        responseMap.put("data", dataMap);
        responseMap.put("sign", "557B1724497D5792813CA573D96A23DB"); // 这里的签名根据实际情况生成
        return responseMap;
    }

    @PostMapping("/gateway/v1/pay/brazil/account/balance")
    public Map queryMchAccount(@Validated @RequestBody AccountQueryRequest request) {

        QueryWrapper<AccountBalance> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_type", "1");
        queryWrapper.eq("mch_no", request.getMchNo());
        queryWrapper.eq("currency", request.getCurrency());
        AccountBalance accountBalance = accountBalanceMapper.selectOne(queryWrapper);
        if (Objects.isNull(accountBalance)){
            Map map = new HashMap();
            map.put("提示", "币种钱包不存在");
            return map;
        }

        // 创建一个 Map 用于存放响应数据
        Map<String, Object> responseMap = new HashMap<>();

        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("balance", AmountUtil.convertCent2Dollar(accountBalance.getAmount(), request.getCurrency())); // 余额
        dataMap.put("frozenBalance", AmountUtil.convertCent2Dollar(accountBalance.getFrozenAmount(), request.getCurrency())); // 冻结余额
        dataMap.put("currency", request.getCurrency()); // 订单创建时间, 13位时间戳

        responseMap.put("code", 0);
        responseMap.put("msg", "SUCCESS");
        responseMap.put("data", dataMap);
        responseMap.put("sign", "EDBF2620B52374178B6BBEF36E0CBBECE77CC4CACF1EE4332A41383819D87D87");
        return responseMap;
    }
}
